package com.hui.demo.service.impl;

import com.hui.demo.dao.UserDao;
import com.hui.demo.error.BussinessException;
import com.hui.demo.model.User;
import com.hui.demo.repository.UserRepository;
import com.hui.demo.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;

/**
 * 用户服务层实现类
 * @author ziv
 * @date 2018-12-07
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UserDao userDao;

    private Logger logger = LogManager.getLogger(this.getClass());

    private static final String ALLUSER = "allUserList";

    @Override
    public User  findById(String userID) {
        // 查询Redis缓存中的所有数据
        List<User> userList = redisTemplate.opsForList().range(ALLUSER, 0, -1);
        if (userList != null && userList.size() > 0) {
            for (User user : userList) {
                if (user.getUserID().equals(userID) ) {
                    return user;
                }
            }
        }
        // 查询数据库中的数据
        User user = userRepository.getOne(userID);
        if (user != null) {
            // 数据插入redis缓存
            redisTemplate.opsForList().leftPushAll(ALLUSER, user);
        }
        return userRepository.getOne(userID);
    }

    @Override
    public List<User> findAll() {
        try {
            System.out.println("开始做任务");
            long start = System.currentTimeMillis();
            List<User> userList = userRepository.findAll();
            long end = System.currentTimeMillis();
            System.out.println("完成任务，耗时" + (end - start) + "毫秒");
            return  userList;
        } catch (Exception e) {
            logger.error("method findAll error", e);
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    public User save(User user) {
        User user2 = userRepository.save(user);

        String error = null;
        error.split("/");
        return user2;
    }

    @Override
    public void delete(String userID) {
        userRepository.deleteById(userID);
        logger.info("userID:" + userID + "用户被删除");
    }

    @Override
    public Page<User> findAll(Pageable pageable) {
        return userRepository.findAll(pageable);
    }

    @Override
    public List<User> findByUserName(String userName) {
        return userRepository.findByUserName(userName);
    }

    @Override
    public List<User> findByUserNameLike(String userName) {
        return userRepository.findByUserNameLike(userName);
    }

    @Override
    public List<User> findByUserIDIn(Collection<String> userIDs) {
        return userRepository.findByUserIDIn(userIDs);
    }

    @Override
    public User findByNameAndPassword(String userName, String password) {
        return userDao.findByNameAndPassword(userName, password);
    }

    @Override
    public Future<List<User>> findAsynAll() {
        try {
            System.out.println("开始做任务");
            long start = System.currentTimeMillis();
            List<User> userList = userRepository.findAll();
            long end = System.currentTimeMillis();
            System.out.println("完成任务，耗时" + (end - start) + "毫秒");
            return new AsyncResult<>(userList);
        } catch (Exception e) {
            logger.error("method findAll error", e);
            return new AsyncResult<>(null);
        }
    }

    @Override
    @Retryable(value = {BussinessException.class}, maxAttempts = 5, backoff = @Backoff(delay = 500, multiplier = 2))
    public User findByNameAndPasswordRetry(String userName, String password) {
        System.out.println("方法 findByNameAndPasswordRetry失败重试了");
        throw new BussinessException();
    }
}
